<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>ADODB Old Session Management Manual</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<style type="text/css">
body, td {
/*font-family: Arial, Helvetica, sans-serif;*/
font-size: 11pt;
}
pre {
font-size: 9pt;
background-color: #EEEEEE; padding: .5em; margin: 0px;
}
.toplink {
font-size: 8pt;
}
  </style>
</head>
<body style="background-color: rgb(255, 255, 255);">
<h3>ADODB Session Management Manual</h3>
<p>V4.94 23 Jan 2007 (c) 2000-2007 John Lim (jlim#natsoft.com.my)</p>
<p><font size="1">This software is dual licensed using
BSD-Style and LGPL. This means you can use it in compiled proprietary
and commercial products. </font>
<p>Useful ADOdb links: <a
	href="http://adodb.sourceforge.net/#download">Download</a> &nbsp; <a
	href="http://adodb.sourceforge.net/#docs">Other Docs</a></p>
<h3>Introduction</h3>
<p>This documentation discusses the old adodb-session.php. Here is
the <a href=docs-session.htm>new documentation</a> on the newer
adodb-session2.php.
<p>We store state information specific to a user or web client in
session variables. These session variables persist throughout a session,
as the user moves from page to page.</p>
<p>To use session variables, call session_start() at the beginning
of your web page, before your HTTP headers are sent. Then for every
variable you want to keep alive for the duration of the session, call
session_register($variable_name). By default, the session handler will
keep track of the session by using a cookie. You can save objects or
arrays in session variables also.</p>
<p>The default method of storing sessions is to store it in a file.
However if you have special needs such as you:</p>
<ul>
	<li>Have multiple web servers that need to share session info</li>
	<li>Need to do special processing of each session</li>
	<li>Require notification when a session expires</li>
</ul>
<p>The ADOdb session handler provides you with the above additional
capabilities by storing the session information as records in a database
table that can be shared across multiple servers.</p>
<p>These records will be garbage collected based on the php.ini
[session] timeout settings. You can register a notification function to
notify you when the record has expired and is about to be freed by the
garbage collector.</p>
<p><b>Important Upgrade Notice:</b> Since ADOdb 4.05, the session
files have been moved to its own folder, adodb/session. This is a
rewrite of the session code by Ross Smith. The old session code is in
adodb/session/old.</p>
<h4>ADOdb Session Handler Features</h4>
<ul>
	<li>Ability to define a notification function that is called when
	a session expires. Typically used to detect session logout and release
	global resources.</li>
	<li>Optimization of database writes. We crc32 the session data and
	only perform an update to the session data if there is a data change.</li>
	<li>Support for large amounts of session data with CLOBs (see
	adodb-session-clob.php). Useful for Oracle.</li>
	<li>Support for encrypted session data, see
	adodb-cryptsession.php. Enabling encryption is simply a matter of
	including adodb-cryptsession.php instead of adodb-session.php.</li>
</ul>
<h3>Setup</h3>
<p>There are 3 session management files that you can use:</p>
<pre>adodb-session.php        : The default<br>adodb-session-clob.php   : Use this if you are storing DATA in clobs<br>adodb-cryptsession.php   : Use this if you want to store encrypted session data in the database<br><br>
</pre>
<p><strong>Examples</strong>
<p>
<pre>
 <font color="#004040">    include('adodb/adodb.inc.php');<br>    <br><b>    $ADODB_SESSION_DRIVER='mysql';<br>    $ADODB_SESSION_CONNECT='localhost';<br>    $ADODB_SESSION_USER ='scott';<br>    $ADODB_SESSION_PWD ='tiger';<br>    $ADODB_SESSION_DB ='sessiondb';</b><br>    <br>    <b>include('adodb/session/adodb-session.php');</b><br>    session_start();<br>    <br>    #<br>    # Test session vars, the following should increment on refresh<br>    #<br>    $_SESSION['AVAR'] += 1;<br>    print "&lt;p&gt;\$_SESSION['AVAR']={$_SESSION['AVAR']}&lt;/p&gt;";<br></font></pre>

<p>To force non-persistent connections, call adodb_session_open()
first before session_start():
<p>
<pre>
 <font color="#004040"><br>    include('adodb/adodb.inc.php');<br>    <br><b>    $ADODB_SESSION_DRIVER='mysql';<br>    $ADODB_SESSION_CONNECT='localhost';<br>    $ADODB_SESSION_USER ='scott';<br>    $ADODB_SESSION_PWD ='tiger';<br>    $ADODB_SESSION_DB ='sessiondb';</b><br>    <br>    <b>include('adodb/session/adodb-session.php');<br>    adodb_sess_open(false,false,false);</b><br>    session_start();<br> </font>
 </pre>
<p>The 3rd parameter to adodb_sess_open($path, $sessname,
$connectMode) sets the connection method. You can pass in the following:</p>
<table width="50%" border="1">
	<tr>
		<td><b>$connectMode</b></td>
		<td><b>Connection Method</b></td>
	</tr>
	<tr>
		<td>true</td>
		<td>
		<p>PConnect( )</p>
		</td>
	</tr>
	<tr>
		<td>false</td>
		<td>Connect( )</td>
	</tr>
	<tr>
		<td>'N'</td>
		<td>NConnect( )</td>
	</tr>
	<tr>
		<td>'P'</td>
		<td>PConnect( )</td>
	</tr>
	<tr>
		<td>'C'</td>
		<td>Connect( )</td>
	</tr>
</table>
<p>To use a encrypted sessions, simply replace the file
adodb-session.php:</p>
<pre> <font color="#004040"><br>    include('adodb/adodb.inc.php');<br>    <br><b>    $ADODB_SESSION_DRIVER='mysql';<br>    $ADODB_SESSION_CONNECT='localhost';<br>    $ADODB_SESSION_USER ='scott';<br>    $ADODB_SESSION_PWD ='tiger';<br>    $ADODB_SESSION_DB ='sessiondb';<br>    <br>    include('adodb/session/adodb-cryptsession.php');</b><br>    session_start();</font><br>
 </pre>
<p>And the same technique for adodb-session-clob.php:</p>
<pre>  <font color="#004040"><br>    include('adodb/adodb.inc.php');<br>    <br><b>    $ADODB_SESSION_DRIVER='mysql';<br>    $ADODB_SESSION_CONNECT='localhost';<br>    $ADODB_SESSION_USER ='scott';<br>    $ADODB_SESSION_PWD ='tiger';<br>    $ADODB_SESSION_DB ='sessiondb';<br>    <br>    include('adodb/session/adodb-session-clob.php');</b><br>    session_start();</font>
 </pre>
<p>An alternative way to set persistant or non-persistent
connections is to call the following function before session_start() is
called.
<pre>
 	ADODB_Session::persist('P'); # 'C' for non-persistent connections
 </pre>
<h4>Installation</h4>
<p>1. Create this table in your database (MySQL syntax):
<p>
<pre> <a name="sessiontab"></a> <font color="#004040">
   create table sessions (
       SESSKEY char(32) not null,
       EXPIRY int(11) unsigned not null,
       EXPIREREF varchar(64),
	   DATA text not null,
	   primary key (sesskey)
	   );</font>
 </pre>

<p>You may want to rename the 'data' field to 'session_data' as
'data' appears to be a reserved word for one or more of the following:
<ul>
	<li>ANSI SQL
	<li>IBM DB2
	<li>MS SQL Server
	<li>Postgres
	<li>SAP
</ul>
<p>If you do, then execute:
<pre>
		ADODB_Session::dataFieldName('session_data');
</pre>
<p>For the adodb-session-clob.php version, create this:
<p>
<pre>
    <font color="#004040"><br>    create table sessions (<br>       SESSKEY char(32) not null,<br>       EXPIRY int(11) unsigned not null,<br>       EXPIREREF varchar(64),<br>       DATA CLOB,<br>      primary key (sesskey)<br>  );</font>
 </pre>
<p>2. Then define the following parameters. You can either modify
this file, or define them before this file is included:
<pre>      <font color="#004040"><br>    $ADODB_SESSION_DRIVER='database driver, eg. mysql or ibase';<br>    $ADODB_SESSION_CONNECT='server to connect to';<br>    $ADODB_SESSION_USER ='user';<br>    $ADODB_SESSION_PWD ='password';<br>    $ADODB_SESSION_DB ='database';<br>    $ADODB_SESSION_TBL = 'sessions'; # setting this is optional<br>	</font>
 </pre>
<p>When the session is created, $<b>ADODB_SESS_CONN</b> holds the
connection object.<br>
<br>
3. Recommended is PHP 4.0.6 or later. There are documented session bugs
in earlier versions of PHP.
<h3>Notifications</h3>
<p>You can receive notification when your session is cleaned up by
the session garbage collector or when you call session_destroy().
<p>PHP's session extension will automatically run a special garbage
collection function based on your php.ini session.cookie_lifetime and
session.gc_probability settings. This will in turn call adodb's garbage
collection function, which can be setup to do notification.
<p>
<pre>
	PHP Session --> ADOdb Session  --> Find all recs  --> Send          --> Delete queued
	GC Function     GC Function        to be deleted      notification      records
	executed at     called by                             for all recs
	random time     Session Extension                     queued for deletion
</pre>
<p>When a session is created, we need to store a value in the
session record (in the EXPIREREF field), typically the userid of the
session. Later when the session has expired, just before the record is
deleted, we reload the EXPIREREF field and call the notification
function with the value of EXPIREREF, which is the userid of the person
being logged off.
<p>ADOdb uses a global variable $ADODB_SESSION_EXPIRE_NOTIFY that
you must predefine before session start to store the notification
configuration. $ADODB_SESSION_EXPIRE_NOTIFY is an array with 2 elements,
the first being the name of the session variable you would like to store
in the EXPIREREF field, and the 2nd is the notification function's name.
</p>
<p>For example, suppose we want to be notified when a user's session
has expired, based on the userid. When the user logs in, we store the id
in the global session variable $USERID. The function name is 'NotifyFn'.

<p>So we define (before session_start() is called):</p>
<pre> <font color="#004040">
	$ADODB_SESSION_EXPIRE_NOTIFY = array('USERID','NotifyFn');
</font></pre>
And when the NotifyFn is called (when the session expires), the $USERID
is passed in as the first parameter, eg. NotifyFn($userid, $sesskey).
The session key (which is the primary key of the record in the sessions
table) is the 2nd parameter.
<p>Here is an example of a Notification function that deletes some
records in the database and temporary files:</p>
<pre><font color="#004040">
	function NotifyFn($expireref, $sesskey)
	{
		global $ADODB_SESS_CONN; # the session connection object
		$user = $ADODB_SESS_CONN-&gt;qstr($expireref);
		
		$ADODB_SESS_CONN-&gt;Execute("delete from shopping_cart where user=$user");          
		system("rm /work/tmpfiles/$expireref/*");
	}</font>  
			  </pre>
<p>NOTE 1: If you have register_globals disabled in php.ini, then
you will have to manually set the EXPIREREF. E.g.</p>
<pre> <font color="#004040">
$GLOBALS['USERID'] = GetUserID();
$ADODB_SESSION_EXPIRE_NOTIFY = array('USERID','NotifyFn');</font>
</pre>
<p>NOTE 2: If you want to change the EXPIREREF after the session
record has been created, you will need to modify any session variable to
force a database record update.</p>
<h4>Neat Notification Tricks</h4>
<p><i>ExpireRef</i> normally holds the user id of the current
session.</p>
<p>1. You can then write a session monitor, scanning expireref to
see who is currently logged on.</p>
<p>2. If you delete the sessions record for a specific user, eg.</p>
<pre>delete from sessions where expireref = '$USER'<br></pre>
then the user is logged out. Useful for ejecting someone from a site.
<p>3. You can scan the sessions table to ensure no user can be
logged in twice. Useful for security reasons.</p>
<h3>Using Oracle CLOBs</h3>
<p>Suppose you are storing the DATA field in a CLOB:
<pre><font color="#004040">
   CREATE TABLE sessions (
       SESSKEY VARCHAR(32) NOT NULL,
       EXPIRY NUMBER(16)  NOT NULL,
       EXPIREREF VARCHAR(64),
       DATA CLOB,
      PRIMARY KEY (sesskey)
  );</font>
 </pre>
<p>Then your PHP code could look like this:
<pre>
	ADODB_SESSION_DRIVER='oci8';
	$ADODB_SESSION_CONNECT=$tnsname;
	$ADODB_SESSION_USER ='scott';
	$ADODB_SESSION_PWD = 'tiger';
	$ADODB_SESSION_DB ='';
	
	$ADODB_SESSION_USE_LOBS = 'clob';
	$ADODB_SESSION_TBL = 'sessions';
	
	$ADODB_SESS_DEBUG=0;
	
	include(ADODB_DIR.'/session/adodb-session.php');
	
	ADODB_Session::persist('P'); # use 'C' for non-persistent connects
	
	session_start();
 </pre>
<p>Note that you can set persistance using
ADODB_Session::persist('P').
<h3>Compression/Encryption Schemes</h3>
Since ADOdb 4.05, thanks to Ross Smith, multiple encryption and
compression schemes are supported. Currently, supported are:
<p>
<pre>  MD5Crypt (crypt.inc.php)<br>  MCrypt<br>  Secure (Horde's emulation of MCrypt, if MCrypt module is not available.)<br>  GZip<br>  BZip2<br></pre>
<p>These are stackable. E.g.
<p>
<pre>ADODB_Session::filter(new ADODB_Compress_Bzip2());<br>ADODB_Session::filter(new ADODB_Encrypt_MD5());<br></pre>
will compress and then encrypt the record in the database.
<h3>adodb_session_regenerate_id()</h3>
<p>Dynamically change the current session id with a newly generated
one and update database. Currently only works with cookies. Useful to
improve security by reducing the risk of session-hijacking. See this
article on <a href=http://shiflett.org/articles/security-corner-feb2004>Session
Fixation</a> for more info on the theory behind this feature. Usage:
<pre>
	$ADODB_SESSION_DRIVER='mysql';
	$ADODB_SESSION_CONNECT='localhost';
	$ADODB_SESSION_USER ='root';
	$ADODB_SESSION_PWD ='abc';
	$ADODB_SESSION_DB ='phplens';
	
	include('path/to/adodb/session/adodb-session.php');
	
	session_start();
	# Every 10 page loads, reset cookie for safety.
	# This is extremely simplistic example, better 
	# to regenerate only when the user logs in or changes
	# user privilege levels.
	if ((rand()%10) == 0) adodb_session_regenerate_id(); 
</pre>
<p>This function calls session_regenerate_id() internally or
simulates it if the function does not exist.
<h3>Vacuum/Optimize Database</h3>
<p>During session garbage collection, if postgresql is detected,
ADOdb can be set to run VACUUM. If mysql is detected, then optimize
database could be called.You can turn this on or off using:</p>
<pre>$turnOn = true; # or false
ADODB_Session::optimize($turnOn);
</pre>
<p>The default for optimization is it is disabled.</p>
<h2>More Info</h2>
<p>Also see the <a href="docs-adodb.htm">core ADOdb
documentation</a>.</p>
</body>
</html>
